#pragma once
#include <plog/Log.h>
#include <plog/Appenders/ColorConsoleAppender.h>
#include <plog/Formatters/TxtFormatter.h>
#include <plog/Initializers/RollingFileInitializer.h>
#include <string>
#include <atomic>
#include <NvInfer.h>

#include "trt_define.h"
_TRT_INFER_BEGIN
class TRTLogger : public nvinfer1::ILogger {
public:
	virtual void log(Severity severity, const char* msg) noexcept override {

		if (severity == Severity::kINTERNAL_ERROR) {
			LOGE << msg;
			abort();
		}else if (severity == Severity::kERROR) {
			LOGE << msg;
		}
		else  if (severity == Severity::kWARNING) {
			LOGW << msg;
		}
		else  if (severity == Severity::kINFO) {
			LOGI << msg;
		}
		else {
			LOGD << msg;
		}
	}
};
class Logger
{
public:
    static Logger& instance()
    {
        static Logger logger;
        return logger;
    }

    void init(plog::IAppender* appender=nullptr, plog::Severity severity = plog::info)
    {
        if (bInited) return;
        if (appender)
        {
            plog::init(severity, appender);
        }
        else
        {
            plog::init(severity, new plog::ColorConsoleAppender<plog::TxtFormatter>());
        }
        bInited = true;
    }

    void addAppender(plog::IAppender* appender)
    {
        plog::get()->addAppender(appender);
        
    }

    void AddTextFileAppender(const std::string& filename, size_t maxFileSize, int maxFiles)
    {
        plog::init(plog::info, new plog::RollingFileAppender<plog::TxtFormatter>(filename.c_str(), maxFileSize, maxFiles));
    }

    plog::IAppender* getLogInstance()
    {
        return plog::get();
    }

    void initCurrentThread(int severity = plog::info)
    {
        init();
        auto logInst = plog::get();
        plog::init((plog::Severity)severity, logInst);
    }

    TRTLogger getTRTLogger()
    {
        return TRTLogger();
    }


private:
    Logger();
    Logger(const Logger&) = delete;
    Logger& operator=(const Logger&) = delete;
    std::atomic<bool> bInited {false};

};

static std::string format(const char* fmt, ...)
{
    va_list vl;
    va_start(vl, fmt);
    char buffer[10000];
    vsprintf(buffer, fmt, vl);
    return buffer;
}


#define LOGER_INST Logger::instance()
_TRT_INFER_END